package com.store.orm.mysql.crud.impl;

import com.store.orm.mysql.MySQLUtil;
import com.store.orm.mysql.crud.Delete;
import com.store.orm.mysql.crud.filter.Filtration;
import com.store.orm.util.MapUtil;
import com.store.orm.util.StringUtil;

import java.util.*;

import static com.store.orm.common.KeyWord.*;

/**
 * @author 宫静雨
 * @version 1.0
 */
public class MySQLDelete implements Delete {
    private MySQLUtil UTIL;

    public MySQLDelete(MySQLUtil UTIL) {
        this.UTIL = UTIL;
    }

    public MySQLUtil getUTIL() {
        return UTIL;
    }

    private Map<String, List<Object>> toResult(String tableName, Map<String, Object> map) {
        StringBuilder sb = new StringBuilder();
        if (map.keySet().size() == 0) {
            if (!UTIL.isTruncate()) {
                throw new RuntimeException("禁止全表删除");
            }
        }
        sb.append(DELETE).append(FROM).append(tableName).append(WHERE);
        map.keySet().forEach(k -> sb.append(k).append(EQUAL_TO).append(QUESTION).append(AND));
        sb.delete(sb.lastIndexOf(AND), sb.length() - 1);
        List<Object> list = new ArrayList<>(map.values());
        return new MapUtil<String, List<Object>>().put(sb.toString(), list).linked();
    }

    private String toResult2(String tableName, Map<String, Object> map) {
        StringBuilder sb = new StringBuilder();
        sb.append(DELETE).append(FROM).append(tableName).append(WHERE);
        map.forEach((k, v) -> UTIL.valDeleteProcessor(sb, k, v));
        sb.delete(sb.lastIndexOf(AND), sb.length() - 1);
        return sb.toString();
    }

    @Override
    public <T> Map<String, List<Object>> delete(T t) {
        Class<?> cls = t.getClass();
        String tableName = UTIL.getTableName(cls);
        Map<String, Object> map = UTIL.parseTToMap(t);
        return toResult(tableName, map);
    }

    @Override
    public <T> List<String> deleteMany(List<T> ts) {
        if (ts.size() == 0) {
            throw new IndexOutOfBoundsException("批量删除时, 数量必须大于0");
        }
        Class<?> cls = ts.get(0).getClass();
        List<String> list = new ArrayList<>();
        ts.forEach(t -> list.add(toResult2(UTIL.getTableName(cls), UTIL.parseTToMap(t))));
        return list;
    }

    @Override
    public Map<String, List<Object>> delete(Class<?> cls, String json) {
        String tableName = UTIL.getTableName(cls);
        Map<String, Object> map = UTIL.parseJsonToMap(json);
        return toResult(tableName, map);
    }

    @Override
    public List<String> deleteMany(Class<?> cls, List<String> jsons) {
        List<String> list = new ArrayList<>();
        String tableName = UTIL.getTableName(cls);
        jsons.forEach(t -> list.add(toResult2(tableName, UTIL.parseJsonToMap(t))));
        return list;
    }

    @Override
    public Map<String, List<Object>> delete(Class<?> cls, LinkedHashMap<String, Object> map) {
        String tableName = UTIL.getTableName(cls);
        return toResult(tableName, map);
    }

    @Override
    public List<String> deleteMany(Class<?> cls, Collection<LinkedHashMap<String, Object>> maps) {
        String tableName = UTIL.getTableName(cls);
        List<String> list = new ArrayList<>();
        maps.forEach(map -> list.add(toResult2(tableName, map)));
        return list;
    }

    @Override
    public String delete(Class<?> cls, Filtration filter) {
        String tableName = UTIL.getTableName(cls);
        String str = filter.get();
        if (StringUtil.isBlank(str)) {
            if (!UTIL.isTruncate()) {
                throw new RuntimeException("禁止全表删除");
            }
        }
        return DELETE + FROM + tableName + BLANK + str;
    }

    @Override
    public List<String> deleteMany(Class<?> cls, Filtration[] filter) {
        String tableName = UTIL.getTableName(cls);
        String sql = DELETE + FROM + tableName + BLANK;
        List<String> list = new ArrayList<>();
        for (Filtration filtration : filter) {
            String str = filtration.get();
            if (StringUtil.isBlank(str)) {
                if (!UTIL.isTruncate()) {
                    continue;
                }
            }
            list.add(sql + str);
        }
        return list;
    }

    @Override
    public String delete(String sql) {
        return sql;
    }

    @Override
    public List<String> deleteMany(String[] sqls) {
        return Arrays.asList(sqls);
    }
}